#include "Graphics.h"
#include <sstream>
Graphics::Graphics(HWND hwnd,int w, int h) : width(w),height(h)
{
	DXGI_SWAP_CHAIN_DESC sd = {};
	sd.BufferDesc.Width = w;
	sd.BufferDesc.Height = h;
	sd.BufferDesc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
	sd.BufferDesc.RefreshRate.Numerator = 0;
	sd.BufferDesc.RefreshRate.Denominator = 0;
	sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
	sd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
	sd.SampleDesc.Count = 1;
	sd.SampleDesc.Quality = 0;
	sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	sd.BufferCount = 1;
	sd.OutputWindow = hwnd;
	sd.Windowed = TRUE;
	sd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
	sd.Flags = 0;

	UINT swapCreateFlags = 0u;
#ifndef NDEBUG
	swapCreateFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

	HRESULT hr;
	hr = D3D11CreateDeviceAndSwapChain(
		nullptr,
		D3D_DRIVER_TYPE_HARDWARE,
		nullptr,
		swapCreateFlags,
		nullptr,
		0,
		D3D11_SDK_VERSION,
		&sd,
		&swapchainPtr,
		&devicePtr,
		nullptr,
		&contextPtr
	);
	if (FAILED(hr)) 
	{
		MessageBox(0, "D3D11CreateDevice Failed.", 0, 0);
		return;
	}
	// RT
	Microsoft::WRL::ComPtr<ID3D11Resource> backbuffer = nullptr;
	HR(swapchainPtr->GetBuffer(0, __uuidof(ID3D11Resource),&backbuffer));
	HR(devicePtr->CreateRenderTargetView(backbuffer.Get(),nullptr,&RTV_Ptr));

	// depth
	Microsoft::WRL::ComPtr<ID3D11Texture2D> m_pDepthStencilBuffer = nullptr;
	D3D11_TEXTURE2D_DESC depthStencilDesc;
	depthStencilDesc.Width = w;
	depthStencilDesc.Height = h;
	depthStencilDesc.MipLevels = 1;
	depthStencilDesc.ArraySize = 1;
	depthStencilDesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
	depthStencilDesc.SampleDesc.Count = 1;
	depthStencilDesc.SampleDesc.Quality = 0;
	depthStencilDesc.Usage = D3D11_USAGE_DEFAULT;
	depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
	depthStencilDesc.CPUAccessFlags = 0;
	depthStencilDesc.MiscFlags = 0;

	HR(devicePtr->CreateTexture2D(&depthStencilDesc, nullptr, m_pDepthStencilBuffer.GetAddressOf()));
	HR(devicePtr->CreateDepthStencilView(m_pDepthStencilBuffer.Get(), nullptr, DSV_Ptr.GetAddressOf()));

	m_pUIManager = std::make_unique<UIManager>();
	m_pUIManager->Initlize(hwnd,devicePtr.Get(),contextPtr.Get());
}

void Graphics::BeginFrame()
{
	m_pUIManager->BeginGUI();
}

void Graphics::EndFrame()
{
	m_pUIManager->EndGUI();
	HR(swapchainPtr->Present(1,0));
}

void Graphics::ClearBuffer(const float* color)
{
	contextPtr->OMSetRenderTargets(1, RTV_Ptr.GetAddressOf(), DSV_Ptr.Get());
	contextPtr->ClearRenderTargetView(RTV_Ptr.Get(),color);
	contextPtr->ClearDepthStencilView(DSV_Ptr.Get(), D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1.0f, 0);
}


ID3D11RenderTargetView ** Graphics::GetRTV()
{
	return this->RTV_Ptr.GetAddressOf();
}

ID3D11DepthStencilView * Graphics::GetDSV()
{
	return this->DSV_Ptr.Get();
}

